home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The 640 MEG Shareware Studio 2
/
The 640 Meg Shareware Studio CD-ROM Volume II (Data Express)(1993).ISO
/
clang
/
nn.zip
/
EXPIRE.C
< prev
next >
Wrap
C/C++ Source or Header
|
1989-12-29
|
4KB
|
198 lines
/*
* Expire will remove all entries in the index and data files
* corresponding to the articles before the first article registered
* in the active file. No attempt is made to eliminate other
* expired articles.
*/
#include "config.h"
#include "db.h"
import int trace;
#define expire_error(msg) { \
err_message = msg; \
goto error_handler; \
}
long expire_group(gh)
register group_header *gh;
{
FILE *old_x, *old_d;
FILE *new;
off_t index_offset, data_offset, new_offset;
long count, expire_count;
char *err_message;
old_x = old_d = new = NULL;
if (trace)
log_entry('T', "Exp %s (%d -> %d)",
gh->group_name, gh->first_l_article, gh->first_article);
/*
* check whether new first article is collected
*/
if (!art_collected(gh, gh->first_article)) {
expire_count = gh->first_l_article - gh->last_l_article + 1;
err_message = NULL;
goto error_handler; /* renumbering, collect from start */
}
expire_count = gh->first_article - gh->first_l_article;
new = NULL;
/*
* Open old files, unlink after open
*/
old_x = open_data_file(gh, 'x', OPEN_READ|OPEN_UNLINK);
old_d = open_data_file(gh, 'd', OPEN_READ|OPEN_UNLINK);
if (old_x == NULL || old_d == NULL)
expire_error("INDEX or DATA file missing");
/*
* Create new index file; copy from old
*/
new = open_data_file(gh, 'x', OPEN_CREATE);
if (new == NULL)
expire_error("INDEX: cannot create");
/*
* index_offset is the offset into the old index file for the
* first entry in the new index file
*/
index_offset = get_index_offset(gh, gh->first_article);
/*
* adjust the group's index write offset (the next free entry)
*/
gh->index_write_offset -= index_offset;
/*
* calculate the number of entries to copy
*/
count = gh->index_write_offset / sizeof(off_t);
/*
* data offset is the offset into the old data file for the
* first byte in the new data file; it is initialized in the
* loop below, by reading the entry in the old index file at
* offset 'index_offset'.
*/
data_offset = (off_t)0;
/*
* read 'count' entries from the old index file starting from
* index_offset, subtract the 'data_offset', and output the
* new offset to the new index file.
*/
fseek(old_x, index_offset, 0);
while (--count >= 0) {
if (!db_read_offset(old_x, &new_offset))
expire_error("INDEX: too short");
if (data_offset == (off_t)0) data_offset = new_offset;
new_offset -= data_offset;
if (!db_write_offset(new, &new_offset))
expire_error("NEW INDEX: cannot write");
}
fclose(new);
fclose(old_x); old_x = NULL;
/*
* copy from old data file to new data file
*/
new = open_data_file(gh, 'd', OPEN_CREATE);
if (new == NULL)
expire_error("DATA: cannot create");
/*
* calculate offset for next free entry in the new data file
*/
gh->data_write_offset -= data_offset;
/*
* calculate number of bytes to copy (piece of cake)
*/
count = gh->data_write_offset;
/*
* copy 'count' bytes from the old data file, starting at offset
* 'data_offset', to the new data file
*/
fseek(old_d, data_offset, 0);
while (count > 0) {
char block[1024];
int count1;
count1 = fread(block, sizeof(char), 1024, old_d);
if (count1 <= 0)
expire_error("DATA: read error");
if (fwrite(block, sizeof(char), count1, new) != count1)
expire_error("DATA: write error");
count -= count1;
}
fclose(new);
fclose(old_d);
/*
* Update group entry
*/
gh->first_l_article = gh->first_article;
/*
* Return number of expired articles
*/
return expire_count;
/*
* Errors end up here.
* We simply recollect the whole group once more.
*/
error_handler:
if (new) fclose(new);
if (old_x) fclose(old_x);
if (old_d) fclose(old_d);
if (err_message)
log_entry('E', "Expire Error (%s): %s", gh->group_name, err_message);
clean_group(gh);
/* will be saved & unblocked later */
/*
* We cannot say whether any articles actually had to be expired,
* but then we must guess...
*/
return expire_count;
}